#include "lib_standard.fxh"
#include "lib_procedurals.fxh"
#include "lib_input.fxh"

void Vertex_Shader(float3 position, float3 normal,float3 tangent, float2 uv1, float2 uv2, float2 uv3, float2 uv4,
				  float4 color, float deformation, out tPixelShaderInput dataOut) {

	dataOut.position_ws	= mul( float4(position,1), World);
	dataOut.hposition	= mul( float4(position,1), mul(World,ViewProj) );
	dataOut.normal		= mul(normal, (float3x3)World);
	dataOut.tangent		= mul(tangent, (float3x3)World);
	dataOut.position_os	= position;
	dataOut.uv12.xy		= uv1;
	dataOut.uv12.zw		= uv2;
	dataOut.uv34.xy		= uv3;
	dataOut.uv34.zw		= uv4;
	dataOut.color		= color;
	dataOut.deformation = deformation;
}

void Instance_Vertex_Shader(float3 position, float3 normal,float3 tangent, float instanceScale, float3 instanceRotate, float3 instancePosition, float2 uv1, float2 uv2, float2 uv3, float2 uv4,
						  float4 color, float deformation, out tPixelShaderInput dataOut) {

	instanceScale *= 10.0f;
	instanceRotate.y *= 5;

	float4x4 RotationY = float4x4(cos(instanceRotate.y), 0, -sin(instanceRotate.y), 0,
		0, 1, 0, 0,
		sin(instanceRotate.y),0 , cos(instanceRotate.y), 0,
		0, 0, 0, 1);

	float4x4 InstanceWorld = float4x4(instanceScale, 0.0f, 0.0f, 0.0f,
									0.0f, instanceScale, 0.0f, 0.0f,
									0.0f, 0.0f, instanceScale, 0.0f,
									instancePosition.x, instancePosition.y, instancePosition.z, 1.0f);

	InstanceWorld = mul(RotationY, InstanceWorld);

	float phase =  Time * 0.2f + (instancePosition.x + instancePosition.z) * 10.0f;
	position += 0.1 * position.z * float3(sin(phase) * 0.1f, 0.0f, cos(phase) * 0.1f);
	dataOut.position_ws	= mul( float4(position,1), InstanceWorld);
	dataOut.hposition	= mul( float4(position,1), mul(InstanceWorld,ViewProj) );
	dataOut.normal		= mul(normal, (float3x3)InstanceWorld);
	dataOut.tangent		= mul(tangent, (float3x3)InstanceWorld);
	dataOut.position_os	= position;
	dataOut.uv12.xy		= uv1;
	dataOut.uv12.zw		= uv2;
	dataOut.uv34.xy		= uv3;
	dataOut.uv34.zw		= uv4;
	dataOut.color		= color;
	dataOut.deformation = deformation;
}

void Pixel_Shader(float3 position_os, float3 position_ws, float3 normal,float3 tangnet, float2 uv1, float2 uv2, float2 uv3, float2 uv4,
				  float4 color, float deformation, float pixeldepth, out float4 outColor) {

	float3 decal;
	float3 specular;
	float3 mask;

	Specular_Combiner(position_os, normal, uv1, mask);

	if(mask.x < 0.1f)
		discard;

	Decal_Combiner(position_os, normal, uv1, decal);
	Normal_Combiner(position_os, normal, uv1, specular);

	specular = (specular * 2) - 1;
	normal = normalize(normal + specular);
	//float3 binormal = normalize(cross(normal, tangnet));
	//normal = normalize(specular.x * tangnet + specular.z * binormal);

	float3 lightingDiffuse;
	float3 lightingAmbinet;
	ComputeLighting(normal, position_ws, 1.0f, 
		lightingDiffuse, lightingAmbinet);
	
	float3 dirtColor = {1,1,1};
	float3 grassColor = color;

	float atmosphereDensity = clamp(pixeldepth * 35, 0, 1);
	float3 atmosphereNear = lightingAmbinet + (lightingDiffuse * decal * lerp(dirtColor, color, clamp(dot(normalize(normal), float3(0,1,0)),0,1)));

	float3 atmosphere = lerp(float3(0.8,0.9,0.95), atmosphereNear, atmosphereDensity);

	outColor.xyz = atmosphere;
	outColor.w = 1;
}